﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Linq.Expressions;

using MvcCmsOptIn.Service;
using MvcCms.Service.Cache;
using MvcCms.Service;
using MvcCmsOptIn.Models;
using MvcCms.Data;
using MvcCms.Service.Helpers;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Web.Hosting;

namespace MvcCmsOptIn.Controllers
{
    [HandleError]
    public class MvcCmsOptInController : MvcCms.Service.Code.BaseClasses.CMSControllerBase
    {
        #region Constructors
        private readonly ICacheService _cacheService;
        private readonly IAccountService _accountService;
        private readonly IOptInService _service;
        public MvcCmsOptInController(ICacheService cacheService, IAccountService accountService, IOptInService optinService, ICmsService cmsService, IZoneService zoneService)
            : base(cmsService, zoneService, accountService)
        {
            _cacheService = cacheService;
            _accountService = accountService;
            _service = optinService;
        }
        #endregion

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult Index()
        {
            ViewBag.Title = "Opt-In Mail Manager";
            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        public ActionResult TrackingImage(int id)
        {
            var newsLetter = _service.GetNewsLetter(id);
            if (newsLetter.Views == null) { newsLetter.Views = 0; }
            newsLetter.Views += 1;
            _service.EditNewsLetter(newsLetter);
            var foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
            var path = HostingEnvironment.MapPath("~/Uploadedimages/" + foldername + "/NewsLetter");

            var bmpIn = (Bitmap)Bitmap.FromFile(Path.Combine(path, "tracking.gif"));
            return new ImageResult { Image = bmpIn, ImageFormat = ImageFormat.Gif };
        }

        #region TrackingLink Methods
        public ActionResult MoreInformation(int id)
        {
            var trackingLink = _service.GetTrackingLink(id);
            if (!trackingLink.Clicks.HasValue) { trackingLink.Clicks = 0; }
            trackingLink.Clicks += 1;
            _service.EditTrackingLink(trackingLink);

            return Redirect(trackingLink.URL);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult AddTrackingLink(int id)
        {
            ViewBag.Title = "Add Tracking Link";
            var newsLetter = _service.GetNewsLetter(id);
            var model = new OptInModel
            {
                _NewsLetter = newsLetter,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddTrackingLink(OptInLinkTracking trackingLinkToAdd)
        {
            ViewBag.Title = "Add Tracking Link";

            var user = _accountService.GetUser();
            trackingLinkToAdd.AdminID = user.UserID;

            if (_service.CreateTrackingLink(trackingLinkToAdd))
            {
                return RedirectToAction("EditTrackingLink", new { id = trackingLinkToAdd.LinkTrackingID });
            }
            ViewBag.Message = "There was a problem creating the list.";
            var newsLetter = _service.GetNewsLetter(trackingLinkToAdd.NewsLetterID);
            var model = new OptInModel
            {
                _NewsLetter = newsLetter,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult EditTrackingLink(int id)
        {
            ViewBag.Title = "Edit Tracking Link";

            var link = _service.GetTrackingLink(id);

            var model = new OptInModel
            {
                _TrackingLink = link,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditTrackingLink(OptInLinkTracking editedLink)
        {
            ViewBag.Title = "Edit Tracking Link";

            var user = _accountService.GetUser();
            var original = _service.GetTrackingLink(editedLink.LinkTrackingID);
            original.URL = editedLink.URL;
            original.Name = editedLink.Name;
            original.AdminID = user.UserID;
            original.CreateDate = DateTime.Now;

            if (!_service.EditTrackingLink(original))
            {
                ViewBag.Message = "There was a problem saving the link.";
            }
            else
            {
                ViewBag.Message = "The link was updated.";
            }

            var model = new OptInModel
            {
                _TrackingLink = original,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteTrackingLink(OptInLinkTracking linkToDelete)
        {
            ViewBag.Title = "Edit List";

            if (!_service.DeleteTrackingLink(linkToDelete.LinkTrackingID))
            {
                ViewBag.Message = "There was a problem deleting the link.";
            }
            else
            {
                return RedirectToAction("Lists");
            }
            var model = new OptInModel
            {
                _TrackingLink = linkToDelete,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View("EditList", "", model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult Links(int id)
        {
            ViewBag.Title = "Opt-In Tracking Links";

            var links = _service.ListTrackingLinks(id);
            var newsLetter = _service.GetNewsLetter(id);

            var model = new OptInModel
            {
                _NewsLetter = newsLetter,
                _TrackingLinks = links,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        #endregion

        #region Subscriber Methods
        public ActionResult Subscription(int id)
        {
            var subscriber = _service.GetSubscriber(id);
            var subscriberLists = subscriber.SubscriberLists;

            var listsForSubscriber = new List<OptInList>();
            IEnumerable<OptInList> availableLists = null;

            foreach (var subscriberList in subscriberLists)
            {
                listsForSubscriber.Add(subscriberList.List);
            }

            var lists = _service.ListLists().Where(l=>l.Private==false);
            if (listsForSubscriber != null)
            {
                var assignedListIds = listsForSubscriber.Select(l => l.ListID);

                availableLists = from list in lists
                                 where !assignedListIds.Contains(list.ListID)
                                 select list;
            }

            var portal = _cacheService.GetCurrentPortal();
            ViewBag.Title = "My NewsLetter Subscriptions at " + portal.DisplayName;
            var model = new OptInModel
            {
                _Subscriber = subscriber,
                _AssignedLists = listsForSubscriber,
                _Lists = availableLists,
                _Portal = portal
            };
            var botGuid = Guid.NewGuid().ToString();
            Session["botGuid"] = botGuid;
            ViewBag.BotGuid = botGuid;
            return View("Subscription", "DontUseMaster", model);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Subscription(OptInSubscriber editedSubscriber)
        {
            var original = _service.GetSubscriber(editedSubscriber.SubscriberID);
            original.Name = editedSubscriber.Name;
            original.Format = editedSubscriber.Format;
            original.EMail = editedSubscriber.EMail;
            original.DoNotContact = editedSubscriber.DoNotContact;

            if (!_service.EditSubscriber(original))
            {
                ViewBag.Message = "There was a problem saving your subscription.";
            }
            else
            {
                ViewBag.Message = "Your subscription was updated.";
            }

            var subscriberLists = original.SubscriberLists;

            var listsForSubscriber = new List<OptInList>();
            IEnumerable<OptInList> availableLists = null;

            foreach (var subscriberList in subscriberLists)
            {
                listsForSubscriber.Add(subscriberList.List);
            }

            var lists = _service.ListLists().Where(l => l.Private == false);
            if (listsForSubscriber != null)
            {
                var assignedListIds = listsForSubscriber.Select(l => l.ListID);

                availableLists = from list in lists
                                 where !assignedListIds.Contains(list.ListID)
                                 select list;
            }

            var portal = _cacheService.GetCurrentPortal();
            ViewBag.Title = "My NewsLetter Subscriptions at " + portal.DisplayName;
            var model = new OptInModel
            {
                _Subscriber = original,
                _AssignedLists = listsForSubscriber,
                _Lists = availableLists,
                _Portal = portal
            };
            var botGuid = Guid.NewGuid().ToString();
            Session["botGuid"] = botGuid;
            ViewBag.BotGuid = botGuid;
            return View("Subscription", "DontUseMaster", model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult ImportFromSite()
        {
            var lists = _service.ListLists();

            ViewBag.Title = "Import Subscribers From Site";
            var model = new OptInModel
            {
                _Lists = lists,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult ImportFromCommaSeperated()
        {
            var lists = _service.ListLists();

            ViewBag.Title = "Import Subscribers From Comma Seperated";
            var model = new OptInModel
            {
                _Lists = lists,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult Subscribers(int id)
        {
            ViewBag.Title = "Opt-In Subscribers";

            if (id >0)
            {
                _service.DeleteSubscriber(id);
            }

            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult AddSubscriber()
        {
            ViewBag.Title = "Add Subscriber";
            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddSubscriber(OptInSubscriber subscriberToAdd)
        {
            ViewBag.Title = "Add Subscriber";

            var subscriberExists = _service.GetSubscriber(subscriberToAdd.EMail);
            if (subscriberExists != null)
            {
                return RedirectToAction("EditSubscriber", new { id = subscriberExists.SubscriberID });
            }

            if (_service.CreateSubscriber(subscriberToAdd))
            {
                return RedirectToAction("EditSubscriber", new { id = subscriberToAdd.SubscriberID });
            }
            ViewBag.Message = "There was a problem creating the subscriber.";
            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult EditSubscriber(int id)
        {
            ViewBag.Title = "Edit Subscriber";

            var subscriber = _service.GetSubscriber(id);
            var subscriberLists = subscriber.SubscriberLists;

            var listsForSubscriber = new List<OptInList>();
            IEnumerable<OptInList> availableLists = null;

            foreach (var subscriberList in subscriberLists)
            {
                listsForSubscriber.Add(subscriberList.List);
            }

            var lists = _service.ListLists();
            if (listsForSubscriber != null)
            {
                var assignedListIds = listsForSubscriber.Select(l => l.ListID);

                availableLists = from list in lists
                                 where !assignedListIds.Contains(list.ListID)
                                 select list;
            }

            var model = new OptInModel
            {
                _AssignedLists = listsForSubscriber,
                _Lists = availableLists,
                _Subscriber = subscriber,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditSubscriber(OptInSubscriber editedSubscriber)
        {
            ViewBag.Title = "Edit Subscriber";

            var original = _service.GetSubscriber(editedSubscriber.SubscriberID);
            original.Name = editedSubscriber.Name;
            original.Format = editedSubscriber.Format;
            original.EMail = editedSubscriber.EMail;
            original.DoNotContact = editedSubscriber.DoNotContact;

            if (!_service.EditSubscriber(original))
            {
                ViewBag.Message = "There was a problem saving the subscriber.";
            }
            else
            {
                ViewBag.Message = "The subscriber was updated.";
            }

            var subscriberLists = original.SubscriberLists;

            var listsForSubscriber = new List<OptInList>();
            IEnumerable<OptInList> availableLists = null;

            foreach (var subscriberList in subscriberLists)
            {
                listsForSubscriber.Add(subscriberList.List);
            }

            var lists = _service.ListLists();
            if (listsForSubscriber != null)
            {
                var assignedListIds = listsForSubscriber.Select(l => l.ListID);

                availableLists = from list in lists
                                 where !assignedListIds.Contains(list.ListID)
                                 select list;
            }

            var model = new OptInModel
            {
                _AssignedLists = listsForSubscriber,
                _Lists= availableLists,
                _Subscriber = original,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }
        #endregion

        #region List Methods

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult AddList()
        {
            ViewBag.Title = "Add List";
            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddList(OptInList listToAdd)
        {
            ViewBag.Title = "Add List";

            var user = _accountService.GetUser();
            listToAdd.AdminID = user.UserID;

            if (_service.CreateList(listToAdd))
            {
                return RedirectToAction("EditList", new { id = listToAdd.ListID });
            }
            ViewBag.Message = "There was a problem creating the list.";
            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult EditList(int id)
        {
            ViewBag.Title = "Edit List";

            var list = _service.GetList(id);

            var model = new OptInModel
            {
                _List = list,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditList(OptInList editedList)
        {
            ViewBag.Title = "Edit List";

            var user = _accountService.GetUser();
            var original = _service.GetList(editedList.ListID);
            original.ListName = editedList.ListName;
            original.Description = editedList.Description;
            original.AdminID = user.UserID;
            original.CreateDate = DateTime.Now;
            original.Private = editedList.Private;

            if (!_service.EditList(original))
            {
                ViewBag.Message = "There was a problem saving the list.";
            }
            else
            {
                ViewBag.Message = "The list was updated.";
            }

            var model = new OptInModel
            {
                _List = original,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteList(OptInList listToDelete)
        {
            ViewBag.Title = "Edit List";

            if (!_service.DeleteList(listToDelete.ListID))
            {
                ViewBag.Message = "There was a problem deleting the list.";
            }
            else
            {
                return RedirectToAction("Lists");
            }
            var model = new OptInModel
            {
                _List = listToDelete,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View("EditList", "", model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult Lists(int? page, string sort)
        {
            ViewBag.Title = "Opt-In Lists";

            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }
        #endregion

        #region NewsLetter Methods
        [Authorize(Roles = "Admin, Editor")]
        public ActionResult SendNewsLetter(int id)
        {
            var newsLetter = _service.GetNewsLetter(id);
            var subscriber = new OptInSubscriber
            {
                SubscriberID=10  //just use a dummy one here
            };
            ViewBag.Title = "Send NewsLetter";

            var recipients = _service.ListListsSubscribers(newsLetter.NewsLetterID);
            var recipientsCommaSeperatedString = String.Join(",", recipients.Select(s => s.SubscriberID.ToString()).ToArray());
            ViewBag.Recipients = recipientsCommaSeperatedString;
            var model = new OptInModel
            {
                _NewsLetter = newsLetter,
                _Subscriber = subscriber,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult EditNewsLetter(int? id)
        {
            var user = _accountService.GetUser();
            var newsletterToEdit = _service.GetNewsLetter(id.GetValueOrDefault());
            var lists = _service.ListLists();
            IEnumerable<OptInList> listsForNewsLetter = null;
            if (newsletterToEdit == null)
            {
                newsletterToEdit = new OptInNewsLetter();
                newsletterToEdit.Subject =  DateTime.Now.Day + " - " +  DateTime.Now.ToString("MMM") + ".  Newsletter";
                newsletterToEdit.Name = DateTime.Now.Day + " - " + DateTime.Now.ToString("MMM") + ".  Newsletter";
                newsletterToEdit.FromName = user.UserName;
                newsletterToEdit.FromEmail = user.Email;
                newsletterToEdit.Status = "Not Saved (New)";
            }
            else
            {
                listsForNewsLetter = newsletterToEdit.Lists;
            }

            IEnumerable<OptInList> availableLists = null;
            if (id>0)
            {
                if (listsForNewsLetter != null)
                {
                    var assignedListIds = listsForNewsLetter.Select(l => l.ListID);

                    availableLists = from list in lists
                                     where !assignedListIds.Contains(list.ListID)
                                     select list;
                }
            }
            else
            {
                availableLists = lists;
            }
            ViewBag.Title = "Edit NewsLetter";
            var model = new OptInModel
            {
                _AssignedLists = listsForNewsLetter,
                _Lists = availableLists,
                _NewsLetter = newsletterToEdit,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteNewsLetter(OptInNewsLetter newsLetterToDelete)
        {
            ViewBag.Title = "Edit NewsLetter";

            if (!_service.DeleteNewsLetter(newsLetterToDelete.NewsLetterID))
            {
                ViewBag.Message = "There was a problem deleting the newsLetter.";
            }
            else
            {
                return RedirectToAction("NewsLetters");
            }
            var model = new OptInModel
            {
                _NewsLetter = newsLetterToDelete,
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View("EditNewsLetter", "", model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult NewsLetters(int? page, string sort)
        {
            ViewBag.Title = "Opt-In NewsLetters";

            var model = new OptInModel
            {
                _Portal = _cacheService.GetCurrentPortal()
            };
            return View(model);
        }

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult DeleteNewsLetter(int id)
        {
            _service.DeleteNewsLetter(id);

            return RedirectToAction("NewsLetters");
        }

        #endregion
    }
}
